package com.hibernate.hrm.controller.employee;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.hibernate.hrm.dao.PositionRepository;
import com.hibernate.hrm.entity.Department;
import com.hibernate.hrm.entity.Position;
import com.hibernate.hrm.entity.User;
import com.hibernate.hrm.service.employee.EmployeeService;
import com.hibernate.hrm.dao.DepartmentRepository;
import jakarta.persistence.EntityNotFoundException;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.web.PageableDefault;
import org.springframework.security.access.AccessDeniedException;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import java.util.List;

@Controller
@RequiredArgsConstructor
public class EmployeeController {

    private final EmployeeService employeeService;
    private final DepartmentRepository departmentRepository;
    private final PositionRepository positionRepository;
    private final PasswordEncoder passwordEncoder;

    @GetMapping("/employee")
    public String employeePage(
            @AuthenticationPrincipal User currentUser,
            @RequestParam(required = false) Integer departmentId,
            @RequestParam(required = false) Integer positionId,
            @RequestParam(required = false) String keyword,
            @PageableDefault(size = 10) Pageable pageable,
            Model model) {

        // 获取角色ID
        int roleIdValue = currentUser.getRoleId().getRoleId();

        // 获取筛选数据
        Page<User> employees = employeeService.searchEmployees(
                currentUser,
                departmentId,
                positionId,
                keyword,
                pageable
        );

        // 使用自定义序列化
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        String employeesJson;
        try {
            employeesJson = mapper.writeValueAsString(employees.getContent());
        } catch (JsonProcessingException e) {
            employeesJson = "[]";
        }

        // 添加模型数据
        model.addAttribute("currentUser", currentUser);
        model.addAttribute("roleIdValue", roleIdValue);
        model.addAttribute("employees", employees);
        model.addAttribute("employeesJson", employeesJson);
        model.addAttribute("departments", departmentRepository.findAll());
        model.addAttribute("positions", positionRepository.findAll());
        model.addAttribute("currentDepartmentId", departmentId);
        model.addAttribute("currentPositionId", positionId);
        model.addAttribute("currentKeyword", keyword);

        return "employee";
    }

    @GetMapping("/employee/add")
    public String addEmployeeForm(@AuthenticationPrincipal User currentUser, Model model) {
        System.out.println("\n==================================");
        System.out.println("||                              ||");
        System.out.println("||        开始加载          ||");
        System.out.println("||                              ||");
        System.out.println("==================================\n");
        model.addAttribute("departments", departmentRepository.findAll());
        model.addAttribute("currentUser", currentUser);
        System.out.println("\n==================================");
        System.out.println("||                              ||");
        System.out.println("||        结束加载          ||");
        System.out.println("||                              ||");
        System.out.println("==================================\n");
        return "employee-add";
    }

    @PostMapping("/employee/add")
    public String addEmployee(
            @AuthenticationPrincipal User currentUser,
            @ModelAttribute User newEmployee,
            @RequestParam String password,
            BindingResult result,
            RedirectAttributes redirectAttributes) {
        System.out.println("\n==================================");
        System.out.println("||                              ||");
        System.out.println("||        开始添加员工          ||");
        System.out.println("||                              ||");
        System.out.println("==================================\n");
        if (result.hasErrors()) {
            redirectAttributes.addFlashAttribute("errorMessage", "请填写所有必填字段");
            return "redirect:/employee/add";
        }

        try {
            employeeService.addEmployee(currentUser, newEmployee, password);
            redirectAttributes.addFlashAttribute("successMessage", "员工添加成功");
            System.out.println("\n==================================");
            System.out.println("||                              ||");
            System.out.println("||        添加成功            ||");
            System.out.println("||                              ||");
            System.out.println("==================================\n");
            return "redirect:/employee";
        } catch (Exception e) {
            redirectAttributes.addFlashAttribute("errorMessage", "添加失败: " + e.getMessage());
            System.out.println("\n==================================");
            System.out.println("||                              ||");
            System.out.println("||        添加失败            ||");
            System.out.println("||                              ||");
            System.out.println("==================================\n");
            return "redirect:/employee/add";
        }
    }

    @GetMapping("/employee/view/{id}")
    public String viewEmployee(
            @AuthenticationPrincipal User currentUser,
            @PathVariable Integer id,
            Model model) {

        // 根据角色权限检查是否有权查看该员工信息
        User employee = employeeService.getEmployeeById(id);
        if (!employeeService.hasViewPermission(currentUser, employee)) {
            throw new AccessDeniedException("无权查看该员工信息");
        }

        model.addAttribute("employee", employee);
        model.addAttribute("currentUser", currentUser);
        model.addAttribute("roleIdValue", currentUser.getRoleId().getRoleId());

        return "employee-view";
    }
    @GetMapping("/employee/edit/{id}")
    public String editEmployeeForm(
            @AuthenticationPrincipal User currentUser,
            @PathVariable Integer id,
            Model model) {

        // 检查编辑权限
        User employee = employeeService.getEmployeeById(id);
        if (!employeeService.hasEditPermission(currentUser, employee)) {
            throw new AccessDeniedException("无权编辑该员工信息");
        }

        model.addAttribute("employee", employee);
        model.addAttribute("currentUser", currentUser);
        model.addAttribute("departments", departmentRepository.findAll());
        model.addAttribute("positions", positionRepository.findAll());
        model.addAttribute("roleIdValue", currentUser.getRoleId().getRoleId());
        model.addAttribute("genders", User.Gender.values());

        return "employee-edit";
    }

    @PostMapping("/employee/edit/{id}")
    public String updateEmployee(
            @AuthenticationPrincipal User currentUser,
            @PathVariable Integer id,
            @ModelAttribute("employee") User updatedEmployee,
            BindingResult result,
            RedirectAttributes redirectAttributes) {

        System.out.println("接收到的更新数据: " + updatedEmployee); // 添加日志
        if (result.hasErrors()) {
            System.out.println("表单验证错误: " + result.getAllErrors()); // 添加错误日志
            return "employee-edit";
        }

        try {
            employeeService.updateEmployee(currentUser, id, updatedEmployee);
            redirectAttributes.addFlashAttribute("successMessage", "员工信息更新成功");
        } catch (Exception e) {
            System.out.println("更新失败: " + e.getMessage()); // 添加异常日志
            redirectAttributes.addFlashAttribute("errorMessage", "更新失败: " + e.getMessage());
        }

        return "redirect:/employee/view/" + id;
    }

    @GetMapping("/employee/delete/{id}")
    public String deleteEmployee(
            @AuthenticationPrincipal User currentUser,
            @PathVariable Integer id,
            RedirectAttributes redirectAttributes) {

        System.out.println("\n==================================");
        System.out.println("||                              ||");
        System.out.println("||        开始删除            ||");
        System.out.println("||                              ||");
        System.out.println("==================================\n");

        try {
            employeeService.deleteEmployee(currentUser, id);
            redirectAttributes.addFlashAttribute("successMessage", "员工删除成功");
            System.out.println("\n==================================");
            System.out.println("||                              ||");
            System.out.println("||        删除成功          ||");
            System.out.println("||                              ||");
            System.out.println("==================================\n");
        } catch (IllegalArgumentException e) {
            redirectAttributes.addFlashAttribute("errorMessage", e.getMessage());
            System.out.println("\n==================================");
            System.out.println("||                              ||");
            System.out.println("||        删除失败1          ||");
            System.out.println("||                              ||");
            System.out.println("==================================\n");
        } catch (Exception e) {
            redirectAttributes.addFlashAttribute("errorMessage", "删除失败: " + e.getMessage());
            System.out.println("\n==================================");
            System.out.println("||                              ||");
            System.out.println("||        删除失败2          ||");
            System.out.println("||                              ||");
            System.out.println("==================================\n");
        }

        return "redirect:/employee";
    }

    @GetMapping("/api/positions/by-department/{departmentId}")
    @ResponseBody
    public List<Position> getPositionsByDepartment(@PathVariable Integer departmentId) {
        return positionRepository.findByDepartmentID_DepartmentID(departmentId);
    }

    @GetMapping("/api/department/by-position/{positionId}")
    @ResponseBody
    public Department getDepartmentByPosition(@PathVariable Integer positionId) {
        Position position = positionRepository.findById(positionId)
                .orElseThrow(() -> new EntityNotFoundException("职位不存在"));
        return position.getDepartmentID();
    }

    @GetMapping("/api/positions/all")
    @ResponseBody
    public List<Position> getAllPositions() {
        return positionRepository.findAll();
    }
}
